﻿using System;
using System.Collections.Generic;
using System.Linq;
using NBlog.Web.Application.Service.Entity;
using NBlog.Web.Application.Service.Internal.Caching;
using NBlog.Web.Application.Storage;

namespace NBlog.Web.Application.Service.Internal
{
    public class BaseService<TEntity> : IBaseService<TEntity>
        where TEntity : BaseEntity, new()
    {
        private readonly IRepository _repository;
        private readonly ICachePolicy _cachePolicy;

        public BaseService(IRepository repository, ICachePolicy cachePolicy)
        {
            _repository = repository;
            _cachePolicy = cachePolicy;
        }

        public void Save(TEntity entity)
        {
            if (string.IsNullOrWhiteSpace(entity.Slug))
                throw new ArgumentNullException("entity", "Entry must have a Slug value to Save()");

            entity.Slug = entity.Slug.ToLowerInvariant();

            if (entity.DateCreated == default(DateTime))
            {
                var isUpdate = Exists(entity.Slug);
                if (isUpdate)
                {
                    var oldEntry = GetBySlug(entity.Slug);
                    entity.DateCreated = oldEntry.DateCreated;
                }
                else
                {
                    entity.DateCreated = DateTime.Now;
                }
            }

            _repository.Save(entity);
        }

        public TEntity GetBySlug(string slug)
        {
            string key = string.Format("{0}_{1}", typeof (TEntity).Name, slug);
            return _cachePolicy.Get(key, () => _repository.Single<TEntity>(slug));
        }

        public List<TEntity> GetList()
        {
            string key = string.Format("All_{0}", typeof(TEntity).Name);
            var entities = _cachePolicy.Get(key, _repository.All<TEntity>);
            return entities.ToList();
        }

        public void Delete(string slug)
        {
            _repository.Delete<TEntity>(slug);
        }

        public bool Exists(string slug)
        {
            string key = string.Format("Exists_{0}_{1}", typeof(TEntity).Name, slug);
            return _cachePolicy.Get(key, () => _repository.Exists<TEntity>(slug));
        }
    }
}